using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace EJet.Admin.Web.Controllers
{
public class FileController : Controller
	{
		#region 上传文件
	
		/// <summary>
		/// Uploads the file.
		/// </summary>
		/// <param name="fileModule">The file module.</param>
		/// <param name="fileList">The file list.</param>
		/// <returns>Task&lt;TData&lt;System.String&gt;&gt;.</returns>
		[HttpPost]
		[DisableRequestSizeLimit]
		public string MergeBigUploadFile([FromServices] IWebHostEnvironment env, string hash, int filecount)
		{


			if (string.IsNullOrEmpty(hash)) return new TData<string> { Message = "hash为空，无法合并文件" };

			string absoluteDir = Path.Combine(env.ContentRootPath, "Resource", "chunkfile", hash);
			if (!Directory.Exists(absoluteDir)) throw new Exception("合并文件不存在，请检查hash值" ); 
			var files = Directory.GetFiles(absoluteDir);
			if (files.Length == 0) throw new Exception("合并文件不存在，请检查hash值"); 
			if (files.Length < filecount)throw new Exception("文件数据不齐，无法合并"); 
			var filename = files.FirstOrDefault(n => n.Contains(".[0_0]"));
			if (string.IsNullOrEmpty(filename))throw new Exception("上传的文件异常，缺少头文件");  
			string bigFileDir = Path.Combine(env.ContentRootPath, "Resource", "BigFile", DateTime.Now.Ticks.ToString());
			if (!Directory.Exists(bigFileDir)) Directory.CreateDirectory(bigFileDir);
			var filepath = Path.Combine(bigFileDir, Path.GetFileName(filename).Replace(".[0_0]", string.Empty));
			var chunkfiles = files.Select(n =>
			{
				var info = Path.GetExtension(Path.GetFileNameWithoutExtension(n)).Replace(".[", string.Empty).Replace("]", string.Empty);
				var index = info.IndexOf("_");
				if (index == -1) return ChunkfileInfo.Empty;
				var off = int.Parse(info.Substring(0, index));
				var length = long.Parse(info.Substring(index + 1));
				return new ChunkfileInfo(off, length, n);
			}).OrderBy(n => n.FileIndex).ToArray();

			using (var stream = new System.IO.FileStream(filepath, FileMode.OpenOrCreate))
			{
				foreach (var item in chunkfiles)
				{
					var buffer = System.IO.File.ReadAllBytes(item.Path);
					if (stream.Position != item.Position) stream.Seek(item.Position, SeekOrigin.Begin);
					stream.Write(buffer, 0, buffer.Length);
					System.IO.File.Delete(item.Path);
				}

			}
			Directory.Delete(absoluteDir);
			var md5 = GetFileMD5(System.IO.File.ReadAllBytes(filepath)).Replace("-", string.Empty);
			if (string.Equals(md5, hash, StringComparison.CurrentCultureIgnoreCase))
			{
				return   filepath.Replace(env.ContentRootPath, string.Empty) ;
			}
            throw new Exception( "文件上传异常，MD5校验不过");
		 
		}
		string GetFileMD5(Stream stream)
		{
			return GetHash(MD5.Create(), stream);
		}
		string GetFileMD5(byte[] stream)
		{
			return GetHash(MD5.Create(), new MemoryStream(stream));
		}
		struct ChunkfileInfo
		{
			public ChunkfileInfo(int fileIndex, long position, string path)
			{
				FileIndex = fileIndex;
				Position = position;
				Path = path;
			}

			public int FileIndex { get; private set; }
			public long Position { get; private set; }
			public string Path { get; private set; }
			public static ChunkfileInfo Empty => new ChunkfileInfo(-1, -1, string.Empty);
			public bool IsEmpty()
			{
				return FileIndex == -1 || Position == -1 || string.IsNullOrEmpty(Path);
			}
		}
		/// <summary>
		/// Uploads the file.
		/// </summary>
		/// <param name="fileModule">The file module.</param>
		/// <param name="fileList">The file list.</param>
		/// <returns>Task&lt;TData&lt;System.String&gt;&gt;.</returns>
		[HttpPost]
		[DisableRequestSizeLimit]
		public void BigUploadFile([FromServices] IWebHostEnvironment env,IFormCollection fileList)
		{

			if (fileList == null || fileList.Files.Count == 0) throw new Exception("未找到相关文件");
			var hash = fileList["hash"];

			if (string.IsNullOrEmpty(hash)) throw new Exception("hash 为空");
			if(fileList.Files.Count==0) throw new Exception("未找到相关文件");

			string absoluteDir = Path.Combine(env.ContentRootPath, "Resource", "chunkfile", hash);
			if (!Directory.Exists(absoluteDir)) Directory.CreateDirectory(absoluteDir);
			var uploadfile = fileList.Files[0];
			var pathFile = Path.Combine(absoluteDir, uploadfile.FileName);
			if (System.IO.File.Exists(pathFile)) System.IO.File.Delete(pathFile);
			var fileStream = uploadfile.OpenReadStream();
			var buffer = new byte[fileStream.Length];
			fileStream.Read(buffer, 0, buffer.Length);
			System.IO.File.WriteAllBytes(pathFile, buffer);
			var md5 = GetFileMD5(buffer).Replace("-", string.Empty);
			var chunkHash = fileList["chunkHash"];
			if (!string.IsNullOrEmpty(chunkHash) && !string.Equals(md5, chunkHash, StringComparison.CurrentCultureIgnoreCase))
			{
				throw new Exception("文件校验不过，丢包");
			}
		}
        #endregion
    }
}